package cn.xueden.common.handler;

import cn.xueden.common.exception.AppException;
import cn.xueden.common.result.Result;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import java.sql.SQLIntegrityConstraintViolationException;

/**功能描述：全局异常处理
 * @author:梁志杰
 * @date:2025/6/8
 * @description:cn.xueden.common.handler
 * @version:1.0
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 自定义异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(AppException.class)
    public Result<String> handleAppException(AppException e){
        log.error(e.getMessage(),e.getClass());
        return Result.failed(e.getLocalizedMessage());
    }

    /**
     * 处理参数校验异常
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        log.error(e.getMessage(),e.getClass());
        String  message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return Result.failed(message);
    }

    /**
     * 处理唯一约束异常
     */

    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public Result<String> handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e){
        log.error(e.getMessage(),e.getClass());
        String message = e.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            message = split[2]+"已存在";
        }
        return Result.failed(message);
    }

    /**
     * 处理请求参数无法解析异常
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException e){
        log.error(e.getMessage(),e.getClass());
        return Result.failed("请求参数无法解析");
    }

    /**
     * 处理请求参数缺失异常
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result<String> handleMissingServletRequestParameterException(MissingServletRequestParameterException e){
        log.error(e.getMessage(),e.getClass());
        return Result.failed("请求参数缺失"+e.getParameterName() + "为必填项");
    }

    /**
     * 处理主键冲突异常
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public Result<String> handleDuplicateKeyException(DuplicateKeyException e){
        String name = e.getMessage().split(":")[2].split(" ")[3];
        log.error(e.getMessage(), e.getClass());
        return Result.failed("主键冲突" + name + "已存在");
    }

    /**
     * 处理无权限访问异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public Result<String> handleAccessDeniedException(AccessDeniedException e){
        log.error(e.getMessage(), e.getClass());
        return Result.failed("你没有该资源的访问权限");
    }
    /**
     * 处理文件太大异常
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result<String> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e){
        log.error(e.getMessage(), e.getClass());
        return Result.failed("上传文件太大");
    }

    /**
     * 处理文件获取不到异常
     */
    @ExceptionHandler(MissingServletRequestPartException.class)
    public Result<String> handleMissingServletRequestPartException(MissingServletRequestPartException e){
        log.error(e.getMessage(), e.getClass());
        return Result.failed("上传文件获取不到");
    }

    /**
     * 处理约束违反异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result<String> handleConstraintViolationException(ConstraintViolationException e){
        log.error(e.getMessage(), e.getClass());
        return Result.failed("约束违反");
    }

    /**
     * 处理其他异常
     */
    @ExceptionHandler(Exception.class)
    public Result<String> handleException(Exception e){
        log.error(e.getMessage(), e.getClass());
        return Result.failed("未知异常");
    }



}
